package com.twu.biblioteca;


import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Scanner;

public class BibliotecaApp {
    BibliotecaApp() {
    }

    private final static String adminAccount = "0000-000";
    private static boolean admin = false;
    private static String cookie;
    public final String[] userHeader = new String[]{"account","password","name","email","phoneNumber"};
    public final String[] bookHeader = new String[]{"id","name","author","year","status"};
    public String[][] books = new String[][]{
            {"00000001","C++ Primer","Stanley B. Lippman","2005",""},
            {"00000002","Think in Java","Bruce Eckel","20020601",""},
            {"00000003","Ruby on Rails","Bruce Tate","20070901",""},
            {"00000004","Refactoring Improving the Design of Existing Code","Martin Fowler","1999",""}};
    public final String[] movieHeader = new String[]{"id","name","director","year","rating","status"};
    public String[][] movies = new String[][]{
            {"00000001","Catch Me If You Can","Steven Spielberg","20061225","unrated",""},
            {"00000002","Inception","Christopher Johnathan James Nolan","20100902","9.2",""},
            {"00000003","Schindler's List","Steven Spielberg","19931130","9.3",""},
            {"00000004","Avatar","James Cameron","20091216","8.7",""},
            {"00000005","The Italian Job","Mark Wahlberg","20030530","7.4",""}};

    public static void main(String[] args) {
        BibliotecaApp bibliotecaApp = new BibliotecaApp();
        if (args.length<2) {
            System.out.println("please input account and password!");
        } else {
            for(String[] user:Account.users) {
                if(user[0].equals(args[0])) {
                    if(user[1].equals(Account.MD5(args[1]))) {
                        if(adminAccount.equals(args[0])) {
                            admin = true;
                        }
                        cookie = args[0];
                        setOnlineStatus(cookie);
                        bibliotecaApp.run();
                    } else {
                        System.out.println("password incorrect!");
                    }
                }
            }
            System.out.println("invalid account!");
        }

    }

    public void run() {
        openItemStatus();
        welcome();
        command();
    }

    private void command() {
        Scanner scanner = new Scanner(System.in);
        scanner.useDelimiter("\n");
        while(scanner.hasNext()) {
            String command = scanner.next();
            switch(command) {
                case "":
                    break;
                case "1":
                case "b":
                case "book":
                    listBook();
                    break;
                case "2":
                case "checkoutBook":
                    checkoutItem(books,"book");
                    break;
                case "3":
                case "return":
                    returnItem(books, "book");
                    break;
                case "4":
                case "m":
                case "movie":
                    listMovie();
                    break;
                case "5":
                case "checkoutMovie":
                    checkoutItem(movies,"movie");
                    break;
                case "6":
                case "returnMovie":
                    returnItem(movies,"movie");
                    break;
                case "9":
                case "o":
                case "onlineUser":
                    listOnlineUsers();
                    break;
                case "0":
                case "q":
                case "quit":
                    tearOnlineStatus(cookie);
                    System.out.println("bye");
                    System.exit(0);
                    break;
                default:
                    help();
                    System.out.println("Select a valid option!");
                    break;
            }
        }
    }

    private void help() {
        System.out.println("1.Book          - list book");
        System.out.println("2.checkoutBook  - checkout book");
        System.out.println("3.returnBook    - return book");
        System.out.println("4.Movie         - list movie");
        System.out.println("5.checkoutMovie - checkout movie");
        System.out.println("6.returnMovie   - return movie");
        if(admin) {
            System.out.println("9.OnlineUsers  -[admin]-  list online users");
        }
        System.out.println("0.Quit          - quit system");
    }

    private void checkoutItem(String[][] items,String name) {
        System.out.print("id? ");
        Scanner scanner = new Scanner(System.in);
        scanner.useDelimiter("\n");
        if (scanner.hasNext()) {
            String id = scanner.next();
            for(String[] item:items) {
                if(item[0].equals(id) && item[item.length-1].equals("")) {
                    saveItemStatus(item[0],name);
                    item[item.length-1] = "by: " + cookie;
                    System.out.println("Thank you! Enjoy the "+name+".");
                    return;
                }
            }
            System.out.println("That "+name+" is not available.");
        }
    }

    private void returnItem(String[][] items,String name) {
        System.out.print("id? ");
        Scanner scanner = new Scanner(System.in);
        scanner.useDelimiter("\n");
        if (scanner.hasNext()) {
            String id = scanner.next();
            for(String[] item:items) {
                if(item[0].equals(id) && !item[item.length-1].equals("")) {
                    tearItemStatus(item[0],name);
                    item[item.length-1] = "";
                    System.out.println("Thank you for returning the "+name+".");
                    return;
                }
            }
            System.out.println("That is not a valid "+name+" to return.");
        }
    }

    private void listBook() {
        final int maxWidth = 25;
        int[] rows = rows(bookHeader,books,maxWidth);
        final String[] masks = mask(rows, " ");
        final String[] masks_ = mask(rows, "_");
        printItems(bookHeader, masks_);
        for(String[] book : books) {
            if(book[book.length-1].equals("") || admin)
                printItems(book, masks);
        }
    }

    private void listMovie() {
        final int maxWidth = 25;
        int[] rows = rows(movieHeader,movies,maxWidth);
        final String[] masks = mask(rows, " ");
        final String[] masks_ = mask(rows, "_");
        printItems(movieHeader, masks_);
        for(String[] movie : movies) {
            if(movie[movie.length-1].equals("") || admin)
                printItems(movie, masks);
        }
    }

    private void listOnlineUsers() {
        final int maxWidth = 25;
        int[] rows = rows(userHeader,Account.users,maxWidth);
        final String[] masks = mask(rows, " ");
        final String[] masks_ = mask(rows, "_");
        printItems(userHeader, masks_);
        for(String[] user : Account.users) {
            if(getOnlineStatus(user[0]))
                printItems(user, masks);
        }
    }

    static class MyFilter implements FilenameFilter {
        private String type;
        public MyFilter(String type){
            this.type = type;
        }
        public boolean accept(File dir,String name){
            return name.endsWith(type);
        }
    }

    private void openItemStatus() {
        String[] names = new File(".").list(new MyFilter(".book"));
        for(String name:names){
            String user = name.substring(0,8);
            String itemId = name.substring(8,16);
            for(int i=0;i<books.length;++i) {
                if(books[i][0].equals(itemId)) {
                    books[i][bookHeader.length-1] = "by:"+user;
                }
            }
        }
        names = new File(".").list(new MyFilter(".movie"));
        for(String name:names){
            String user = name.substring(0,8);
            String itemId = name.substring(8,16);
            for(int i=0;i<movies.length;++i) {
                if(movies[i][0].equals(itemId)) {
                    movies[i][bookHeader.length-1] = "by:"+user;
                }
            }
        }
    }

    private void saveItemStatus(String itemId, String name) {
        String fileName = cookie + itemId+"."+name;
        File file = new File(fileName);
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void tearItemStatus(String itemId, String name) {
        String fileName = cookie + itemId+"."+name;
        File file = new File(fileName);
        if(file.exists()) {
            file.delete();
        }
    }

    private static boolean getOnlineStatus(String id) {
        File file = new File(id + ".user");
        return file.exists();
    }

    private static void setOnlineStatus(String id) {
        File file = new File(id + ".user");
        try {
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void tearOnlineStatus(String id) {
        File file = new File(id + ".user");
        if(file.exists()) {
            file.delete();
        }
    }

    private void printItems(String[] items, String[] masks) {
        int i=0;
        for(String item:items) {
            StringBuilder buff= new StringBuilder(masks[i]);
            buff.replace(0, item.length(), item);
            int row = masks[i].length();
            if(item.length()> row) {
                buff.setLength(row-3);
                System.out.print(buff+"...|");
            } else {
                buff.setLength(row);
                System.out.print(buff+"|");
            }
            ++i;
        }
        System.out.println("");
    }


    private String[] mask(int[] rows, String mask) {
        String[] masks = new String[rows.length];
        int i=0;
        for(int row:rows) {
            String space = "";
            for(int j=0;j<row;++j) {
                space += mask;
            }
            space = space.substring(0,row);
            masks[i++] = space;
        }
        return masks;
    }

    private int[] rows(String[] header, String[][] items, final int maxWidth) {
        int[] rows = new int[header.length];
        {
            int i=0;
            for (String head : header) {
                if (head.length() > rows[i]) {
                    rows[i] = head.length() < maxWidth ? head.length() : maxWidth;
                }
                ++i;
            }
        }
        for(String[] item : items) {
            int i=0;
            for (String value:item) {
                if(value.length()>rows[i]) {
                    rows[i] = value.length() < maxWidth ? value.length() : maxWidth;
                }
                ++i;
            }
        }
        return rows;
    }

    private void welcome() {
        System.out.println("Welcome Biblioteca!");
    }
}
